package com.program.facesigninsystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.program.facesigninsystem.dao.ISignInActivityDao;
import com.program.facesigninsystem.dao.ISignInRecordDao;
import com.program.facesigninsystem.entity.ResponseModel;
import com.program.facesigninsystem.entity.SignInActivity;
import com.program.facesigninsystem.entity.SignInRecord;
import com.program.facesigninsystem.iteration.dto.ListContent;
import com.program.facesigninsystem.iteration.dto.NoSignInParam;
import com.program.facesigninsystem.iteration.dto.TemplateInfoAmend;
import com.program.facesigninsystem.iteration.entity.*;
import com.program.facesigninsystem.iteration.mapper.*;
import com.program.facesigninsystem.service.ISignInRecordService;
import com.program.facesigninsystem.util.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;

@Service
@Slf4j
public class SignInRecordService implements ISignInRecordService {
    @Autowired
    private ISignInRecordDao iSignInRecordDao;
    @Autowired
    private ISignInActivityDao iSignInActivityDao;
    @Resource
    UserMapper userMapper;
    @Resource
    SigninrecordMapper signinrecordMapper;
    @Resource
    UserSigninclassMapper userSigninclassMapper;
    @Resource
    SigninlinkMapper signinlinkMapper;
    @Resource
    SigninclassMapper signinclassMapper;
    @Resource
    RedisTemplate redisTemplate;


    @Override
    public List<Map<String, Object>> selectRecordList(String lid) {
        return iSignInRecordDao.selectRecordList(lid);
    }

    @Override
    public int selectRecCount(String lid) {
        return iSignInRecordDao.selectRecCount(lid);
    }


    @Override
    public int selectRecCount1(String lid,int num) {
        if(num==1){
            return iSignInRecordDao.selectRecCount1(lid);
        }else if(num==2){
            return iSignInRecordDao.selectRecCount2(lid);
        }else if(num==3){
            return iSignInRecordDao.selectRecCount3(lid);
        }else if(num==4){
            return iSignInRecordDao.selectRecCount4(lid);
        }else if(num==5){
            return iSignInRecordDao.selectRecCount5(lid);
        } else {
            return iSignInRecordDao.selectRecCount6(lid);
        }
    }
    @Override
    public List<Map<String, Object>> selectNoSignIn(String cid, String lid) {
        return iSignInRecordDao.selectNoSignIn(cid, lid);
    }

    @Override
    public void addNewRecord(String id, String lid, String uid, String createTime, String state,String state2) {
        String normal = "normal";
        if (normal.equals(state)) {
            iSignInRecordDao.addNewRecord(id, lid, uid, createTime);
        } else {
            iSignInRecordDao.addNewRecordWithState(id, lid, uid, createTime, state,state2);
        }
    }

    @Override
    public List<SignInRecord> selectRecord(String uid, String date1, String date2) {
        return iSignInRecordDao.selectRecord(uid, date1, date2);
    }

    @Override
    public List<SignInRecord> selectRecordByMonth(String uid, String date) {
        return iSignInRecordDao.selectRecordByMonth(uid, date);
    }

    @Override
    public List<SignInRecord> selectRecordAll(String uid) {
        return iSignInRecordDao.selectRecordAll(uid);
    }

    @Override
    public SignInRecord selectRecExist(String uid, String lid) {
        return iSignInRecordDao.selectRecExist(uid, lid);
    }

    @Override
    public List<Map<String, Object>> selectRank() {
        return iSignInRecordDao.selectRank();
    }

    @Override
    public List<Map<String, Object>> selectMyRecord(String uid, String date) {
        return iSignInRecordDao.selectMyRecord(uid, date);
    }

    @Override
    public List<Map<String, Object>> selectList(String lid) {
        return iSignInRecordDao.selectList(lid);
    }

    @Override
    public void signinByTea(String id, String uid, String lid, String createTime, String state) {
        iSignInRecordDao.signInByTea(id, uid, lid, createTime, state);
    }

    @Override
    public void signinByTea2(String id, String name, String lid, String createTime, String state) {

        UserEntity userEntity = userMapper.selectOne(new QueryWrapper<UserEntity>().eq("name", name));
        iSignInRecordDao.signInByTea(id, userEntity.getUid(), lid, createTime, state);
    }

    @Override
    public void exportExcel(String fileName, String lid, HttpServletRequest request, HttpServletResponse response, List<Map<String, String>> noSignIn) {
        List<Map<String, Object>> dataList;
        SignInActivity signInActivity = iSignInActivityDao.selectAct(lid);
        String cid = signInActivity.getCid();
        //寻找已签到学生
        dataList = iSignInRecordDao.findSignIn(lid);
        if (!cid.equals("")) {
            List<Map<String, Object>> list;
            //寻找未签到学生
            if (noSignIn.size() != 0) {
                for (int i = 0; i < noSignIn.size(); i++) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", noSignIn.get(i).get("name"));
                    map.put("studentId", noSignIn.get(i).get("studentId")); // 添加学号
                    map.put("state", "未签到");
                    map.put("academy", null);
                    map.put("major", null);
                    map.put("class_name", null);
                    map.put("signintime", null);
                    dataList.add(map);
                }
            } else {
                list = iSignInRecordDao.findNoSignIn(cid, lid);
                dataList.addAll(list);
            }
        } else {
            //寻找未签到学生
            if (noSignIn.size() != 0) {
                for (int i = 0; i < noSignIn.size(); i++) {
                    Map<String, Object> map = new HashMap<>();
                    map.put("name", noSignIn.get(i).get("name"));
                    map.put("studentId", noSignIn.get(i).get("studentId")); // 添加学号
                    map.put("state", "未签到");
                    map.put("academy", null);
                    map.put("major", null);
                    map.put("class_name", null);
                    map.put("signintime", null);
                    dataList.add(map);
                }
            }
        }
        List<String> titleList = Arrays.asList("序号", "签到人", "学号",  "签到结果", "签到时间", "班级", "专业", "学院");
        ExcelUtil.uploadExcelAboutUser(request, response, fileName, titleList, dataList);
    }

    @Override
    public void exportExcel2(String fileName, String lid, HttpServletRequest request, HttpServletResponse response) {
        List<Map<String, Object>> dataList;
        SignInActivity signInActivity = iSignInActivityDao.selectAct(lid);
        String cid = signInActivity.getCid();
        //寻找已签到学生
        dataList = iSignInRecordDao.findSignIn(lid);
        if (!cid.equals("")) {
            List<Map<String, Object>> list;
            //寻找未签到学生
            list = iSignInRecordDao.findNoSignIn(cid, lid);
            dataList.addAll(list);
        }
        List<String> titleList = Arrays.asList("序号", "签到人", "签到结果", "签到时间", "班级", "专业", "学院");
        ExcelUtil.uploadExcelAboutUser(request, response, fileName, titleList, dataList);
    }

    @Override
    public ResponseModel selectDistinctState(String lid) {
        List<Map<String, Integer>> map = iSignInRecordDao.selectDistinctState(lid);
        Map<String, Object> data = new HashMap<>(2);
        data.put("count", map.size());
        data.put("list", map);
        return new ResponseModel(200, "获取成功", data);
    }


    @Override
    public ResponseModel setSignInState(String uid, String lid, String state) {
        try {
            iSignInRecordDao.setSignInState(uid, lid, state);
            return new ResponseModel(200, "修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseModel(198, "修改失败");
        }
    }

    @Override
    public List<NoSignInParam> getNoSignIn(String lid, String cid) {

        return iSignInRecordDao.getNoSignInList(lid, cid);
    }

    @Override
    public void exportSignInRecord(String[] actIdList, int signInClassId, int[] titleList, HttpServletRequest request, HttpServletResponse response) {

        String key = "temp-" + signInClassId + "export";
        //获取名单中的所有人留作对比
        List<UserSigninclassEntity> userSigninclassEntityList = userSigninclassMapper.selectList(new QueryWrapper<UserSigninclassEntity>().eq("signinclass_id", signInClassId));
        int totalTimes = 0;
        for (String actId : actIdList) {

            List<SigninlinkEntity> signinlinkEntityList = signinlinkMapper.selectList(new QueryWrapper<SigninlinkEntity>().eq("actid", actId).eq("status", 1));
            for (SigninlinkEntity signinlinkEntity : signinlinkEntityList) {
                totalTimes++;
                List<SigninrecordEntity> signinrecordEntityList = signinrecordMapper.selectList(new QueryWrapper<SigninrecordEntity>().eq("lid", signinlinkEntity.getLid()));

                for (SigninrecordEntity signinrecordEntity : signinrecordEntityList) {
                    //一个个通过名字插到redis里
                    UserEntity userEntity = userMapper.selectOne(new QueryWrapper<UserEntity>().eq("uid", signinrecordEntity.getUid()));
                    String hashValue = null;
                    Object object = redisTemplate.opsForHash().get(key, userEntity.getName());
                    if (object != null) {
                        String[] records = object.toString().split("-");
                        switch (signinrecordEntity.getState()) {
                            case "签到":
                                hashValue = (Integer.valueOf(records[0]) + 1) + "-" + records[1] + "-" + records[2] + "-" + records[3] + "-" + records[4];
                                break;
                            case "未认证":
                                hashValue = records[0] + "-" + (Integer.valueOf(records[1]) + 1) + "-" + records[2] + "-" + records[3] + "-" + records[4];
                                break;
                            case "迟到":
                                hashValue = records[0] + "-" + records[1] + "-" + (Integer.valueOf(records[2]) + 1) + "-" + records[3] + "-" + records[4];
                                break;
                            case "请假":
                                hashValue = records[0] + "-" + records[1] + "-" + records[2] + "-" + (Integer.valueOf(records[3]) + 1) + "-" + records[4];
                                break;
                            case "其他":
                                hashValue = records[0] + "-" + records[1] + "-" + records[2] + "-" + records[3] + "-" + (Integer.valueOf(records[4]) + 1);
                                break;
                        }
                        redisTemplate.opsForHash().put(key, userEntity.getName(), hashValue);
                    }
                    else {
                        switch (signinrecordEntity.getState()) {
                            case "签到":
                                redisTemplate.opsForHash().put(key, userEntity.getName(), "1-0-0-0-0");
                                break;
                            case "未认证":
                                redisTemplate.opsForHash().put(key, userEntity.getName(), "0-1-0-0-0");
                                break;
                            case "迟到":
                                redisTemplate.opsForHash().put(key, userEntity.getName(), "0-0-1-0-0");
                                break;
                            case "请假":
                                redisTemplate.opsForHash().put(key, userEntity.getName(), "0-0-0-1-0");
                                break;
                            case "其他":
                                redisTemplate.opsForHash().put(key, userEntity.getName(), "0-0-0-0-1");
                                break;
                        }
                    }
                }

            }
        }

        List<Map<String, Object>> dataList = new ArrayList<>();
        for (UserSigninclassEntity userSigninclassEntity : userSigninclassEntityList) {

            Map<String, Object> map = new HashMap<>();
            Object object = redisTemplate.opsForHash().get(key, userSigninclassEntity.getName());
            if (object != null){
                String[] records = object.toString().split("-");
                int signTimes = Integer.valueOf(records[0]) + Integer.valueOf(records[1]) + Integer.valueOf(records[2]) + Integer.valueOf(records[3]) + Integer.valueOf(records[4]);
                map.put("name", userSigninclassEntity.getName());
                map.put("signTimes", signTimes);
                map.put("noSignTimes", totalTimes - signTimes);
                map.put("noCertification", Integer.valueOf(records[1]));
                map.put("beLate", Integer.valueOf(records[2]));
                map.put("askForLeave", Integer.valueOf(records[3]));
                map.put("else", Integer.valueOf(records[4]));
                double signRate = signTimes / ((double)totalTimes) * 100;
                map.put("signRate", signRate + "%");
                double beLateRate = Integer.valueOf(records[2]) / ((double)totalTimes) * 100;
                map.put("beLateRate", beLateRate + "%");
            }else {
                map.put("name", userSigninclassEntity.getName());
                map.put("signTimes", 0);
                map.put("noSignTimes", totalTimes);
                map.put("noCertification", 0);
                map.put("beLate", 0);
                map.put("askForLeave", 0);
                map.put("else", 0);
                map.put("signRate", 0  + "%");
                map.put("beLateRate",  0  + "%");
            }
            dataList.add(map);
        }

        List<String> titleLists = new ArrayList<>();
        titleLists.add("序号");
        titleLists.add("签到人");
        for (int i : titleList) {
            switch (i) {
                case 0:
                    titleLists.add("签到次数");
                    break;
                case 1:
                    titleLists.add("未签到次数");
                    break;
                case 2:
                    titleLists.add("未认证次数");
                    break;
                case 3:
                    titleLists.add("迟到次数");
                    break;
                case 4:
                    titleLists.add("请假次数");
                    break;
                case 5:
                    titleLists.add("其他");
                    break;
            }
        }
        if (titleLists.contains("签到次数"))
            titleLists.add("签到率");
        if (titleLists.contains("迟到次数"))
            titleLists.add("迟到率");

        // 设置正确的 Content-Type 和文件名
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("签到结果.xlsx", "UTF-8"));
            response.setCharacterEncoding("UTF-8");

            ExcelUtil.uploadExcelAboutSigninRecord(request, response, "签到结果", titleLists, dataList);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete(key);
        }
    }
}
